PART -1: intro/preamble

[3]**
	-download the slides at: [++TODO: URL to slides.. metanet/tutorials/fitc05.zip?]

who am i
	-one of two people who made N
	-we've been using flash since v5 (i.e since actionscript was useful and easy to use)

<short demo of N, just watch a mainmenu replay>**

	-promo blurb: "N is a platform/run-and-jump game which combines oldschool gameplay 
	  with modern collision detection + physics simulation"

	-we made N with flash prove that flash/actionscript could be used for "real video games"


[4]**	-"the curse of sylvaniah" (by Strille/Luxregina) is another great game which also proves our point: 
	 games made in flash can be "real video games"


[5]**	-collision detection is a vast feild of research
	-impossible to cover properly in an hour.
	 -i'll present specific methods well-suited for use in flash/actionscript
		-some of the ideas we used in N, as well as some of the stuff we've learnt since making N	
	-there is a LOT of stuff to cover

	-i'm going to try to introduce you to the ideas involved without a lot of technical detail
		-understand the concepts,  independent from the implementation of the concept
		-there WILL be some code and formulas and stuff
			-it's more important to understand the meaning behind the code and formulas. 

	-you can check out our online tutorials if you need to look at source.

	-warning: i'm a programmer. these slides count as "programmer art".

	-ask:
		-how many people know what a vector is?
		-how many people know what a dotproduct is?
	

[6]**
-to begin:
	-this lecture is about collision detection
	-implicitly, it's about game programming in flash
	-game programming in flash feels a bit wrong. 
		-it certainly wasn't made for video games. 
		-there is a sense of "we're abusing this platform"
	-but we're going to write games in flash anyway, so why not try to do it well.
	-i'll start by trying to convince you about why collision detection matters
	-then i'll discuss some solutions for dealing with collision detection



MOTIVATION:
	
	-why does collision detection matter? is it only useful for ninja platformers?
[7]**	-no. a lot of games would benefit from better collision detection/response
		-everyone's favorite, the top-view racing game
		-pool, pinball, 
		-basketball/sports (show McShitOut and/or scribball demo)
		-platforming games
[8]**		-most importantly: _new_ types of genre-defying games which you're going to invent next week
[9]**	-having a good collision detection+response system enables a wide range of (otherwise inaccessible) gameplay possibilities.


[10]**
-HitTest:  	
	-why do we need to learn about collision detection? 
	-doesn't flash already have built-in collision detection?
		-yes, but it has two major weaknesses
			1: only returns a yes/no answer
			2: only works with axis-aligned rectangles

[11]**		-what can you do with a yes/no answer?: 
[12]**			-destroy one/both objects 
[13]**			-move one/both objects to old position
[14]**			-reverse direction of one/both objects
			-or any combination of the above

[15]**		-what can't you do with a yes/no answer?: 
[16]**			-friction and bounce
[17]**			-sliding along obstacles
[18]**			-rotating to orient to the ground
			-etc.	

[19]**		-what can you do with axis-aligned rectangles?:
			-anything! ..as long as it involves unrotated rectangles

[20]**		-what can't you do with axis-aligned rectangles?: 
			-circles
			-concave surfaces
			-curved or angled surfaces
			-rotating shapes
			-etc.

[21]**	-using hittest, if you need more than a yes/no answer about a collision, you can use "tricks": 
		-sample multiple points on an object
		-from the multiple yes/no results, infer information about the collision direction, etc.
		
	-if you work hard enough, you _might_ get it to work..

[22]**	-it will be slower than it needs to be (due to the number of calls to hittest)
	-it won't work 100% of the time (because you're relying on implied/approximated and not actual information)
	-it just doesn't feel as solid as "the real thing"


[23]**	-HitTest is awesome -- if you're living in the 80s 
		-lots of moving rectangles which explode when they touch each other
	-if you want to actually respond to collisions in a meaningful way, HitTest isn't enough
	-meaningful collision response requires meaningful information about the collision.
	-better information, better response, better games, better "feel"
	-ultimately, "real" (non-HitTest) collision detection enables "physics"


-physics?!
[24]**	-in video games this year, "physics is the new graphics".. everyone wants more physics in their games.
	-one common misconception is that "physics" means "slow and complex code". physics doesn't have to be complicated or slow.
 
<demo ragdoll>**

[25]**	-"physics" is a much-abused term. 
		-most of the time it just means "things moving".
		-if you've ever written "position += velocity" or "newpos = oldpos + velocity", 
		 you've already been using "physics". 
		-what are you afraid of?

[26]**	-the only math you need to know is some vector algebra/geometry which we'll cover
		-no trig: trig is horrible
			-it's very difficult to develop an intuition about it
			-it's very hard to visualize when thinking about a problem
		-vectors are your friends
			-they can be used to replace trig in 99% of situations
			-they are easy to visualize and develop intuitions about

[27]**	-most importantly: flash vs. SNES
		-way less graphical power, way more processing power

	-flash can't compete with modern (or even classic) video games when it comes to graphical power
		-consoles and PCs have dedicated graphics hardware; flash has only got the CPU

	-flash CAN compete in terms of processing power and memory
		-the SNES (which came out in 1991) had the same processor as an apple IIgs.. 
		-even with the overhead of the flashplayer VM, flash outperforms the SNES in terms of both speed and complexity
			-double-precision floating point, which lets us do a lot of things which simply weren't possible on an SNES
			-because of the overhead of the flash VM, "expensive" ops like sqrt() aren't
			  really much more expensive than any other math op (+, -, etc.)
				-this gives us flexibility to pursue different solutions (which might not be tractable on other platforms)
			-flashplayer has built-in support for sophisticated structures like hashmaps (i.e "objects") 
			 and dynamic memory management
				-this makes it easier for us to explore complex ideas than possible on a SNES

[28]**	-so: flash games have the ability to compete with modern (or classic) video games on the battlefield known as "gameplay"						
		-collision detection and physics are two great tools for developing novel gameplay

[29]**	-some examples of games that are using collision detection and physics to create different types of gameplay
[30]**
[31]**
[32]**

	-hopefully you're now motivated


[33]**
PART 0: collision response

-collision response is important to mention breifly because it provides the motivation for collision detection
	-see our website for tutorials and links to more info

-collision response is _why_ you need a collision detection solution that's more informative than HitTest
	-collision detection provides you with information describing a collision; 
	-if you don't _use_ this information in a meaningful way, CD is moot

[34]**	-collision response "in a nutshell":
		-there are many different ways to handle collision response
		-they all of the need to know the same thing

[35]**			-penetration direction, penetration amount
				-pdir*pamt = penetration vector, projection vector, etc.
			-i may use "penetration vector" and "projection vector" interchangeably

[36]**		-one thing we want to do when notified of a collision is prevent the two colliding objects from continuing to collide
		-a simple solution to this is "projection"
			-given two colliding objects and their penetration vector
				-translate (move) one object by the penetration vector
				-OR: translate both objects by 1/2 the penetration vector
				-etc.. playing with the ratios allows the simulation of objects with different relative mass
					-i.e heavy objects aren't moved very much

[37]**		-aside from preventing the objects from continuing to overlap, you can modify their properties based on the direction of the collision surface 
			-penetration vector describes the surface direction of the collision
			-you can measure the velocity of objects parallel to and perpendicular to the surface
				-we'll cover the math later, it's simple vector projection
[38]**				-you break the object's velocity down into those two components 
				-scale each component seperately/differently, and recombine them to get the post-collision velocity
				-this lets you simulate friction/bounce

		-you can also let game logic make decisions based collision information
					-rotating object graphics so that they align themselves to the ground
					-inflicting damage for violent collisions
					 (the object's velocity perpendicular to the surface tells you how violent the collision was)

<demo: level 0-0, ninja skidding around and rotating to match the surface of things>**
<demo: level 0-0, ninja falling to death>**




[39]**	
PART 1: narrow-phase collision detection, aka object-vs-object testing

[40]**	-so, what we need to do when performing collision detection on a pair of shapes is:
		(a) determine if the two shapes are colliding, and if so 
		(b) calculate the penetration vector which describes the collision

[41]**	-actually.. that's only half of the collision detection problem. 
	-the other half is knowing which pairs of shapes to test in the first place

[42]**	-these two parts of the collision detection process are often called "narrow" and "broad" phase collision detection
		-broad = figuring out which pairs of objects we must test
		-narrow = testing each pair
	-sort of like sifting through something: start with a coarse filter to elliminate most things, then use a fine-grained filter on the remaining stuff

-we'll start with narrow-phase and then discuss broad-phase

-i'll try to answer questions breifly after each section
-i'd prefer to stick to specific questions (i.e if i'm not explaining something in detail)
-leave larger questions for Q&A at the end of the presentation


-there are several different approaches to object-vs-object tests; the one i'm going to describe is based on something called "the method of seperating axes" <todo: refer to ginoVDB and geomtools books>
	-it's well-suited for flash
		-fast (faster than any other method we've seen)
		-simple (easy to understand, easy to code)
		-flexible (easy to adapt to many different situations)

[43]**
-the method of seperating axes, in english
	-there will be a lot of "axis" talk
		-axis really just means "direction". any time you hear "axis", you can mentally substitute "direction". 
		-1 vector, many vertices
		-1 axis, many axes

[44]**	-the Method of Seperating Axes is based on the Seperating Axis Theorem: 
		-a mathmatical theorem about the properties of convex polygons
[45]**		-thus, this method only works for convex shapes 
			-what is a convex shape? probably you've at least got an intuitive understanding of convexity.
				there are many "practical" definitions: 
				-no internal angles <= 180deg
				-a line connecting any two points inside the shape is contained within the shape
				-only lefthand turns when walking CCW around the surface
				-etc.


[46]**	-Seperating Axis Theorem, part 1:
		-if two convex polygons don't overlap, then there must be a direction along which they are "seperated"
		-the converse is also true: if there is no direction which seperates two objects, the objects must be overlapping
		-"seperated" means that, if we look at the world along that direction, there is a space between the two shapes
			-the direction we look along is called an axis
				-if the two objects are seperated, it's a seperating axis
			-you could think of it as a line through the objects; it's offset in diagrams to make it less cluttered/confusing
<diagram: show seperated and overlapping cases>


[47]**	-Seperating Axis Theorem, part 2: 
		-we don't have to test _all_ directions; if there is a seperating axis, then it must be perpendicular to an edge of one of the shapes
		-so, instead of testing all possible directions to find a seperating axis, 
		 we only test those directions which are perpendicular to the edges of our polygons
<diagram: as before, but point out/focus on normal directions>

	-there's a proof for the SAT, but that's (thankfully) outside the scope of this lecture
		-we didn't invent this method, we just noticed that other game programmers were using it


[48]**	-the Method of Seperating Axes is a method of collision detection which is based on SAT:
			-given two shapes, determine all the potentially seperating axes for those shapes
				-i.e determine the directions which are perpendicular to each edges of each polygon
			-test each potentially seperating axis until we find an axis along which the objects are seperated
			-if we've tested all potentially seperating axes and found none that are seperating the objects, 
			 the objects are colliding

	-instead of a single, complicated 2D test (based on minimum distance or whatever), we perform a series of simple 1D tests
		-each test is along a different direction, or "axis"
		-each test boils down to a few lines of very simple (and fast) math 
			-we'll get to the math shortly

	-the strength of this method is the "early out"
		-we don't need to test every potentially seperating axis; as soon as we find an axis which seperates the two shapes,
		 we know (thanks to the SAT) they can't be colliding and we can skip the rest of the axes
		-this means when two objects aren't colliding, we do less work than when they are
		-in a typical game, any two objects picked at random are likely NOT colliding, 
	  	 so optimising the not-colliding case makes sense and really speeds things up
	


[49]**	-before we get into actual code, let's review some basic vector algebra/geometry
	-basic vector math: nothing to be afraid of

[50]**	-vectors (difference of two points)

[51]**	-unit vectors/direction
		-unit vectors: vectors whose length is 1
		-very useful to use these to represent directions, INSTEAD of angles/radians/etc.
			-they've got some useful properties which we'll see in a moment
		-formula/code:
			-basically, you divide x and y components by the length of the vector
			-null (0-length) vectors don't work
		-when you multiple a unit vector by a scalar X, the result is a vector which points in the same 
		  direction as the unit vector, but which is X units long
		-in this presentation, whenever you hear "axis" (and/or "direction"), this means normalized unit vector
		-the process of taking a vector and scaling it until it's unit-length is called "normalization"
			-the vector has been normalized
			-NOT to be confused with the following


[52]**	-normal vectors (NOT to be confused with normalized vectors! althouth.. normal vectors are often normalized..)
		-perpendicular to a vector 
		-formula/code: it's so simple it's weird that the results are meaningful/useful
		-each vector has two of these, LH and RH

[53]**		-by convention, polygon edges are arranged in CCW order
			-this means that each edge's RHnorm points "out" of the polygon edge
		-these are of special importance to us: the RHnorms of each edge of a polygon _are_ the potentially seperating axes we must test


[54]**	-dotproduct
		-in highschool you may have learnt a definition of dotprod involving cosine: 
			-AdotB = |A|*|B|*cos(angle between A and B)
			-this is irrelevant
		-dotprod is a measure of the relative directions of two vectors
		-formula/code: as with normal vectors, it's so simple it's weird that the results are meaningful/useful
		-the important thing to note is that:
			-when two vectors point in the same direction, their dp is at maximum value
			-then they point in opposite directions, their dp is at minimum value
			-when they're perpendicular to each other, their dp is 0

[55]**		-if vector A is unit length and vector B isn't, the min/max values of their dp are -/+ the length of B
			-the value of the dp is no longer just some value, it's now "meaningful": 
				-it's the _length_ of vector B when "measured along" the direction described by vector A
				-"measured along, viewed along, the length of the image of B on A", etc.
			-this is important for projection


[56]**	-vector projection
		-just one multiplication step added onto the end of a dotprod
		-as we just learnt, when vector A is unit length, and vector B isn't, 
		 AdotB gives you the length of the "image" of B, when measured along A

		-we can make a vector of length AdotB, which is parallel to A
			-just multiply A (unit vector) by AdotB 
			-that vector is called the projection of B onto A
			-you can think of it as "B when viewed/measured along the line containing A"
				-mapping 2D to 1D

[57]**		-this is the core of our method: projecting shapes onto each potentially seperating axis
			-if we only care about the length of the projected vector (i.e the dotproduct), we can use the dotproduct itself
		-this is also what we use for friction/bounce 
			-as we saw earlier, you decompose object velocity into two perp. components
		  	 by projecting them onto the surface direction


[58]**	-the method of seperating axes, revisited
		-the if(overlap) step is "where all the action is"

[59]**	-example: Box vs. Box
		-figure out which axes we have to test
			-aside: normally, testing two quadrilaterals would involve testing 8 potentially seperating axes 
			 (4 from each quad) 
				-boxes are a special case which exploit the SAT's rules
					-we need to test all directions which are perpendicular to the surface of each shape
					-since, for each box, a single direction is perp. to two surfaces, 
					 we can perform a single axis test for each pair of opposite box edges
		-anyway:
			-calculate the object-object delta vector (vector from center of one object ot center of the other)
			-for each potentially seperating axis (show all 4 axes, then show each step below on a single axis):
				-calculate the projected halfsize of each object (projected = when measured along the axis) (BLUE)
				-calculate the projected length of the delta vector (projected = when measured along the axis) (GREEN)
				-calculate the difference between the sum of the halfsizes, and the delta vector
					-if negative, we've found a seperating axis and we can stop: the shapes don't overlap
					-if positive, objects overlap along the axis, continue testing (RED)
[60]**		-if, after testing each axis, we still haven't found a seperating axis, then the objects must be colliding


[61]**	-what??!? i'm confused..
		-why are we using this weird concept of "halfsize"?
		-don't we still end up with only a yes/no answer? i thought this approach was supposed to give us more info
		-..wait a minute.
	-this might seem familiar.

[62]**	-one very useful insight for understanding this approach is that it's a generalisation of circle-circle collision detection 
	 (which everyone is probably familiar with)

[63]**	-circle-circle <diagram each step>
		-calculate the object-object delta vector
		-for each potentially seperating axis (in this case, there's only one: the axis which passes through both circles' centers)
			-calculate distance between circles
				-SAT: calculate the projected size of the delta vector (in this case, this is == the length of the delta vector)
			-calculate sum of radii
				-SAT: calculate the projected halfsize of each object (in this case, this is == their radius)
			-calculate the difference between the sum of halfsizes/radii and the delta vector
				-if positive, objects overlap along the axis

[64]**		-not only does this help us understand what's going on in our SAT test, 
		 it also suggests how to get more than a yes/no answer from the results
			-do whatever we do in the circle-circle case

		-if the circles ARE overlapping 
				-the penetration direction is parallel to the axis
				-the amount is equal to the difference we calculated (sum-of-radii minus size-of-delta)

[65]**	-Box-vs-Box revisited
		-it's the same process as with two circles, except that we have to test more than just a single potentially seperating axis
		-each axis test is analogous to the circle-circle test, they just involve a bit more math, to project things onto the axis.. 
			-in the circle case, the object halfwidths and delta vectors are parallel to the axis
			-as we saw with dotprods, when you project a vector onto an axis that's parallel to the vector, you get the 
			 original vector
				-like multiplying any number by 1
			 -so, for circles, the values are basically "pre-projected" and we skip the projection math
		-as soon as we find a seperating axis, we're done -- we know the objects don't overlap

[66]**		-as with circles, if the objects ARE overlapping (i.e we tested all axes and none are seperating the two objects), 
		  we can extract collision info "for free" from the per-axis calculations we made
			-the axis with the smallest "difference" (sum-of-halfsizes minus size-of-delta) is the projection direction
			-the size of the difference is the projection amount
			-projection direction + projection amount = projection vector. tada!


[67]**	-so, we can use this method to collide any two shapes together, provided that for each shape we can quickly determine:
		a) which directions are perpendicular to the shape's surface 
			(i.e which axes are potentially seperating directions for that shape)
		b) how to project the shape onto an axis, i.e
			-the shape's center (when projected onto an axis)
			-the shape's size/halfsize (when projected onto an axis)


[68]**	-example: projecting a box onto an axis
		-this is code for an arbitrarily rotated box (in the diagrams, we're just keeping the box still and moving the axis..)
			-it's the same thing/relativity
		-an important insight for box projection is: 
			the sum of the projections of the halfwidth vectors = projected halfwidth of box
			<point to diagram of this>

[69]**		-box representation:
			-position (of box center)
			-width/height (along object axes)
			-unit vector (describing orientation of box; we use the convention that the orientation vector points along local x)
		
		-see our tutorials for examples of how to project different shapes
			-linesegs should be obvious


[70]** -step through Box-vs-Box code line-by-line, examining/explaining it

	-point out that you COULD make the code more generic/general
		-each shape has an array of unit vectors representing potential seperating axes
		-each shape has a function "Project" which return the object's halfsize when projected onto a given axis
	-however, if you want to it run as fast as possible, writing special code for each possible combination of objects is the best solution


[71]** 	-what we left out:
		[66]** might help when explaining this
		-tracking minimum penetration axis
			-store all pen amounts and compare them at the end, or keep a "running minimum"
		-which direction to project? 
			-projdir is parallel to the axis of minimum projection, but could point in two possible directions
			-use the sign of the delta<dot>axis
			

[72]**-what about circles?
		-we haven't mentioned circles or curved surfaces yet, but they're very useful as collision shapes
		-the main difference between circles and polygons is the behaviour around corners (vertices)
			-circles "roll" around corners: the collision direction changes smoothly
			-polygons slide across them: the collision direction remains the same (surface normal)
<demo: use tutorialA demo: circle falling/sliding off the top of a square>**	
<demo: as above, but use an AABB falling/sliding off the top of a square>**
	
	-another way to look at this difference is that, unlike polygons, 
	 there aren't a finite/discrete number of directions perpendicular to a circle's surface
	-this is a problem, since our approach relies on knowing which directions might be potentially seperating directions	
	-but: since this SAT approach is a sort of generalization of circle-circle collision, 
	  surely we can support circles without too much extra work

[73]**	-we can
	-instead of reiterating what's presented in our online tutorials, i'll just refer you to them
	-the basic idea is that for a circle you perform the exact same tests as you would for a box, except you sometimes 
	 perform a single additional test at the end 
		-to handle the case where the circle is colliding with a "corner" (vertex) of a shape instead of an edge (lineseg)
	-you don't always have to perform this test	
	-there is a fast and simple way to determine if you have to perform this additional test
			-you can use information from the axes you've already tested
			-if the overlap along the box axes is less than the circle's radius, we know the circle is in a corner region
	<demonstrate the above values/etc. with the diagram>	
		-if the circle's center is in the horiz/vertical regions, we only test the two box axes
			-we can tell if the circle is in these regions by looking at the results of these 2 axis tests
		-if the circle's NOT in these regions, we have to test it vs. the nearest box corner
			-again, which corner to use is easy since part of the 2 axis tests was determining the box->circle delta vector
			-this delta vector "points" at the box corner

[74]**	-what about non-convex shapes?
		-this is important, especially for world/level shapes 
		-just represent them as a union of convex shapes 
			-several (possibly overlapping) convex shapes
[75]**		-tilebased games use the same idea: decompose the world into small chunks
[76]**		-a different decomposition is: linesegs
			-this is leading into the next section into broad-phase
		


[77]**	-optimisations: 
		-the key is to precompute as much information as possible, so that you don't have to calculate it at runtime
		-instead you just lookup your precomputed value
	-almost every game subscribes to the rule: "the vast majority of things in the world are static"
		-i.e the game code makes a distinction between (static) world/level geometry, and (dynamic) objects	
		-makings things static is a great optimisation because we can precompute almost everything about each static object
	-triangles and more complex shapes are harder to project than a box
		-more lines of code
		-you _can_ still do it on the fly, it's just slower
		-calculations for circles and boxes are very fast and simple; they make good candidates for dynamic objects
		-more complex shapes can be used for static objects, since most of the calculations 
		 (calculating surface normals aka axis directions, etc.) can be done beforehand instead of at runtime




[78]** QUESTIONS about Seperating Axis Thereom / Method of Seperating Axes

[++TODO: figure out how much time we can spend here, and note it down so that, when presenting, we don't get stuck here for too long]




[79]** 
PART 2: broad-phase collision detection, aka spatial database
	-switching gears...

[80]** 	-knowing how to test two objects for collision is only part of the solution to the CD problem
[81]**		-if there are 10 objects in the world, we'd have to perform 10*10=100 tests
		-it doesn't matter how fast your object-object test is if you're using it 100 times per frame
		-for N objects, you have to use N^2 tests

[82]**	-we want to be able to very quickly determine which pairs of objects we should test, i.e which pairs MIGHT be colliding
		-how to figure out what might be colliding?
		-all the methods i know of for broad-phase CD use the assumption: 
			if two objects are near each other, then they might be colliding
		-quickly == approximately; we don't need to know for sure, that's the job of the narrow-phase
		-once we know which pairs MIGHT be colliding, we can pass them to our narrow-phase collision system 
		  to figure out if they actually _are_ colliding, and if so, how.
	-so, we just need to find a way to quickly determine, given an object or a position in the world, 
	  all of the other objects nearby
		
	-this step is _very_ game specific
		-there is no "magic bullet"

[83]**	-for small numbers of objects (<=5), using HitTest on each possible pair is often "good enough"
		-you're still doing N^2 tests, but you're not doing too many of them, and they're not too expensive
		-it's fast, and it tells you what you need to know (that the objects might be colliding)
			-if HitTest returns true, you know their bounding boxes are overlapping, and can investigate further using complex tests
		-however, for the sake of argument, SAT code for AABBs (i.e rectangles) can be just as fast as Hittest
			-the main cost is the overhead of a function call


[84]**	-for larger numbers of objects, you need a more sophisticated way to find all the objects near a given point
	-this problem has been solved in many different ways: 
		-grid: divide space into uniform boxes
[85]**		-quadtree: recursively subdivide space into 4 equal regions

[86]**	-they all amount to the same thing: partitioning space into discrete chunks, and building a database using those chunks
		-the data in the database is the location of objects
		-hence broad-phase collision systems are often called spatial databases

	-the two most important operations on this database are:
		a) neighborhood query (quickly determining which objects are near a given position)
		b) updating an entry in the database (i.e moving an object)
	-optimising (a) is very simple if you don't care about (b)
	-games which must support large numbers of moving objects must optimise (b)
	-it's hard to do both at once; this is why broad-phase is so game-specific


[87]**	-grids are best for flash
		-there are many different ways to use grids, but ALL of them are better suited for flash than non-grid-based methods
		
	-why only grids? 

		-grids allow for constant-time neighborhood queries, and constant-time updating 
			-the constant cost is extremely low
			-for a neighborhood query, you simply find the cell which contains your query point, 
			 then look in the surrounding cells
			-to update the position of an object in the grid, you just need to find the cells which the object touches, 
			  which is fast and simple
				-more on this later

		-all other spatial database approaches are based on search-trees of some sort
			-the quadtree i showed you LOOKED sort of like a grid, but the implementation looks 
			  like a normal tree data structure
				-each node has 4 children, etc.
			-when you look something up from a tree, you have to descend to the leaves, performing tests at each level of the tree
				-each test takes time
				-grids only require one test, not one test per level of the heirarchy
			-likewise, inserting something into a tree is more complex than with a grid

		-if grids are so good, why don't other games use them?
			-most 2D games _do_ use grids
				-obviously, any tile-based game is using some sort of grid
				-even doom used grid-based collision

[88]**			-the problem with grids is that they take up a LOT of space, since the entire world must be covered in cells
				-a 200x100-tile world means a grid with 20000 cells; if each cell needs 256bytes, that's 5MB
				-in 3D, this only gets worse: 200x100x100 @ 256bytes = 500MB
			-this is why trees are used; they require far less memory. instead of covering the entire world, 
			  you only cover the non-empty parts of the world
			-the tradeoff is that trees are slower and more complex to query and update

[89]**		-in flash, in 2D, you can afford the extra memory needed by a grid, but you _can't_ afford the extra processing time required by trees


[90]**	-all grid operations involve a couple math ops
		-you can't get any faster than that

[91]**	-using a grid for object-vs-object tests
		-i'll just provide an outline of the process
			-see our online tutorials for implementation details and source code

[92]**	-a grid is just an abstract data structure; there are many differnet ways to actually use the structure.
	-two popular ways are "regular" and "loose" grids
	<explain the following in english while using diagram to illustrate>

	-regular grid:
		-every object knows which grid cell(s) it touches
		-every grid cell knows which object(s) are touching it
		<refer to diagram> 
			each blue cell must be tested for collision, and each blue cell must be updated when objects move

	-loose grid:
		-every object knows which grid cell contains it's center
		-every cell knows which object(s) it contains
		<refer to diagram>
			each red cell must be tested for collision, and each blue cell must be updated when objects move

	-regular vs. loose:
		-less tests	vs	less time to update moving objects
		-can handle any sized shape	vs	shapes must fit in a cell
	
	

[93]**	-using a grid for object-vs-world
		-as mentioned earlier, most games divide objects into "static" and "dynamic" groups
		-you CAN simply use the grid to collide dynamic vs. static objects exactly as you 
		  would for dynamic vs. dynamic objects (as we just saw)
	-however, if you know that most of the game world will consist of static shapes, 
	 you might want to create a special system for colliding these static shapes against dynamic objects		


[94]**	-there isn't time to explore all of the possible ways to use a grid for object-vs-world tests
		-i'll breifly cover 2 approaches
		-tilebased and geometry-based

	-tilebased collision: 
		-each grid cell stores a tile shape
		-each moving object collides against all other moving objects and tiles in it's neighborhood
			-again, our online tutorials cover this topic very well (i'd rather not just repeat info that's already available)
		-tilebased systems SEEM like a good choice (simple and fast)
			-in practise they're quite hard to get good behaviour out of
			-tilebased collision is usually rule-based instead of math-based; 
			  rule-based works well for simple dynamic models, but when you start needing smooth 
			  physics-based object movement, rule-based collision simply doesn't perform well
			-you end up doing lots of extra work to get things behaving well
			-doing lots of extra work defeates the purpose of using a tilebased world in the first place, which was speed and simplicity

	-a different grid-based approach is geometry/lineseg based
		-the world is made out of polygons
			-convex or concave, it doesn't matter
		-as a preprocess, before runtime, you decompose your polygons into their component linesegs
			-insert each lineseg into a grid
			-determining which cells to insert a lineseg into can be done in several ways
				-since it's a preprocess it doesn't really matter how slow this code is
				-you can simply try lineseg-vs-AABB test for all cells touching the lineseg's bounding box
				-or you can use raycast code (which we'll touch on soon)
		-at runtime, object-vs-world collision involves one or two object-vs-lineseg tests
			-linesegs are the simplest and fastest shapes to collide against
				-they have only a single potentially seperating axis
			-performing several object-vs-lineseg tests is MUCH faster than performing 
			  several object-vs-tileshape tests 
	-this system can support the exact same levels and shapes as a tilebased system
		-but it's far simpler 
			-instead of having many different possible tile-shapes to collide against, you have just one shape: lineseg
		-it's also a lot faster 
			-testing vs. linesegs is faster than vs. timeshapes



[95]** -another great advantage that grids have over other spatial databases is: raycasting is very easy
		-rays are lines with one endpoint
		-they're used to model fast-moving bullets in many games (doom, quake)
		-they're also very useful for line-of-sight testing (AI uses these to determine what each enemy can "see")
	
[96]**	-a very efficient and simple to understand raycasting algorithm is presented in this paper
		-it's very simple, and very fast
		-yet again, please see our online tutorials for implementation details



[97]**
PART 3: misc/conclusion

-summary:
	-collision detection is a powerful tool for making fun games
	-the MSA is a useful tool for narrow-phase collision detection
	-a uniform grid is a useful tool for broad-phase collision detection

-QUESTIONS?





